diff -Naur hydra-5.4-src.orig/hydra-ssh2.c hydra-5.4-src/hydra-ssh2.c
--- hydra-5.4-src.orig/hydra-ssh2.c	2007-03-22 14:04:29.000000000 +0000
+++ hydra-5.4-src/hydra-ssh2.c	2009-12-18 03:12:56.000000000 +0000
@@ -7,12 +7,51 @@
 }
 #else
 
-#warning "If compilation of hydra-ssh2 fails, you are not using v0.11. Download from http://www.0xbadc0de.be/"
+#warning "If compilation of hydra-ssh2 fails, you are not using v0.4. Download from http://www.libssh.org/"
 
 #include <libssh/libssh.h>
 
 extern char *HYDRA_EXIT;
 
+/* try to authenticate with one password */
+static int
+try_password(ssh_session ssh_session, char *password){
+  int auth_state;
+  int i;
+  /* printf("ssh-trying pass \"%s\"\n",password); */
+  /* We try keyboard-interactive when it's supported. kbdint is
+   * what openssh tries first when logging somewhere.
+   */
+  auth_state = ssh_userauth_kbdint(ssh_session, NULL, NULL);
+  if(auth_state == SSH_AUTH_INFO){
+    i=0;
+    /* we feed 10 password responses at max. Keybint is challenge-response
+     * based so the server could ask unrelated questions
+     */
+    while(auth_state == SSH_AUTH_INFO && i<10){
+      ssh_userauth_kbdint_setanswer(ssh_session, i, password);
+      auth_state = ssh_userauth_kbdint(ssh_session, NULL, NULL);
+      i++;
+    }
+    /* Partial authentication is specific to SSH : the password is valid but
+     * an other authentication token is needed (generaly private key)
+     */
+    if(auth_state == SSH_AUTH_PARTIAL)
+        auth_state = SSH_AUTH_SUCCESS;
+    if(auth_state == SSH_AUTH_INFO)
+        auth_state = SSH_AUTH_ERROR;
+    return auth_state;
+  }
+  if(auth_state == SSH_AUTH_ERROR)
+    return auth_state;
+  /* Keyboard-interactive is not supported so we run through the password
+   * method */
+  auth_state = ssh_userauth_password(ssh_session, NULL, password);
+  if(auth_state == SSH_AUTH_PARTIAL)
+    auth_state = SSH_AUTH_SUCCESS;
+  return auth_state;
+}
+
 int
 start_ssh2(int s, unsigned long int ip, int port, unsigned char options, char *miscptr, FILE * fp)
 {
@@ -21,17 +60,17 @@
   char *buf;
   char *rc;
   struct sockaddr_in targetip;
-  SSH_SESSION *ssh_session;
-  SSH_OPTIONS *ssh_opt;
+  ssh_session ssh_session;
+  char buffer[64], firstlogin[128];
   int auth_state;
-  int i = 0;
+  const int btrue = 1;
 
   if (strlen(login = hydra_get_next_login()) == 0)
     login = empty;
   if (strlen(pass = hydra_get_next_password()) == 0)
     pass = empty;
 
-  ssh_opt=options_new();
+  ssh_session=ssh_new();
   memset(&targetip, 0, sizeof(targetip));
   memcpy(&targetip.sin_addr.s_addr, &ip, 4);
   targetip.sin_family = AF_INET;
@@ -41,16 +80,18 @@
   buf = malloc(20);
   inet_ntop(AF_INET, &targetip.sin_addr, buf, 20);
 #endif
-  options_set_wanted_method(ssh_opt,KEX_COMP_C_S,"none");
-  options_set_wanted_method(ssh_opt,KEX_COMP_S_C,"none");
-  options_set_port(ssh_opt, port);
-  options_set_host(ssh_opt, buf);
-  options_set_username(ssh_opt, login);
-
-  if ((ssh_session = ssh_connect(ssh_opt)) == NULL) {
+  snprintf(firstlogin,sizeof(firstlogin),"%s",login);
+  ssh_options_set(ssh_session, SSH_OPTIONS_SSH1, &btrue);
+  ssh_options_set(ssh_session, SSH_OPTIONS_PORT, &port);
+  ssh_options_set(ssh_session, SSH_OPTIONS_HOST, buf);
+  ssh_options_set(ssh_session, SSH_OPTIONS_USER, login);
+  /* printf("ssh-connecting with login \"%s\"\n",login); */
+  if (ssh_connect(ssh_session) == SSH_ERROR) {
     rc = ssh_get_error(ssh_session);
     if ((rc != NULL) && (rc[0] != '\0')) {
-      if (strncmp("connect:", ssh_get_error(ssh_session), strlen("connect:")) == 0)
+      snprintf(buffer,sizeof(buffer),"%s",rc);
+      ssh_disconnect(ssh_session);
+      if (strncmp("connect:", buffer, strlen("connect:")) == 0)
         return 3;
       else
         return 4;
@@ -60,43 +101,54 @@
   free(buf);
   buf = NULL;
 #endif
-
-  do {
-    /* why this crap? */
-    auth_state = ssh_userauth_kbdint(ssh_session, login, NULL);
-    while (i < 10 && auth_state == SSH_AUTH_INFO) {
-      ssh_userauth_kbdint_setanswer(ssh_session, i, pass);
-      auth_state = ssh_userauth_kbdint(ssh_session, login, NULL);
-      i++;
-    }
-    
-    if (auth_state == SSH_AUTH_SUCCESS || ssh_userauth_password(ssh_session, login, pass) == SSH_AUTH_SUCCESS) {
-      ssh_disconnect(ssh_session);	/* this automagically frees the ssh_opt buffer */
-      hydra_report_found_host(port, ip, "ssh2", fp);
-      hydra_completed_pair_found();
-      if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
-        return 2;
-      /* free(ssh_opt); */ /* DOUBLE FREE ! */
+  /* None method is important since it can flag passwordless servers */
+  auth_state=ssh_userauth_none(ssh_session, login);
+  if(auth_state == SSH_AUTH_SUCCESS){
+    /* passwordless server */
+    hydra_report_found_host(port, ip, "ssh2", fp);
+    hydra_completed_pair_found();
+    ssh_disconnect(ssh_session);
+    if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
+      return 2;
+    else
       return 1;
-    } else {
-      if (ssh_error_code(ssh_session) == 1) {
-        hydra_completed_pair();
+  }
+ 
+  do {
+    auth_state=try_password(ssh_session, pass);
+      if (auth_state == SSH_AUTH_SUCCESS) {
+        ssh_disconnect(ssh_session);	/* this automagically frees the ssh_opt buffer */
+        hydra_report_found_host(port, ip, "ssh2", fp);
+        hydra_completed_pair_found();
         if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
           return 2;
+        return 1;
       } else {
-        ssh_disconnect(ssh_session);	/* this automagically frees the ssh_opt buffer */
-        hydra_completed_pair(); /* really? */
-        if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
+        if (auth_state == SSH_AUTH_DENIED) {
+        hydra_completed_pair();
+        if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0){
+          ssh_disconnect(ssh_session);
           return 2;
-        /* free(ssh_opt); */ /* DOUBLE FREE ! */
+          }
+        /* set a new password to try */
+        login=hydra_get_next_login();
+        if(strcmp(login,firstlogin) != 0){
+            /* we can't try a new login without a new session. */
+            ssh_disconnect(ssh_session);
+            //hydra_completed_pair_skip();
+            return 1;
+        }
+        pass=hydra_get_next_password();
+        /* try again using same session */
+      } else {
+        ssh_disconnect(ssh_session);	/* this automagically frees the ssh_opt buffer */
+        /* there was an error. The password was not really tried.*/
+        //hydra_completed_pair_skip();
         return 1;
       }
     }
   } while(1);
 
-  /* not reached */
-
-  /* free(ssh_opt); */ /* risk of double free */
   return 1;
 }
 
